package com.arpa.ntocc.common.service.authorize;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alicp.jetcache.Cache;
import com.alicp.jetcache.anno.CreateCache;
import com.arpa.ntocc.common.common.constant.StrConsts;
import com.arpa.ntocc.common.common.exception.PermissionException;
import com.arpa.ntocc.common.common.util.HttpUtil;
import com.arpa.ntocc.common.domain.dto.UserInfoDTO;
import com.arpa.ntocc.common.domain.entity.*;
import com.arpa.ntocc.common.domain.enums.ClientTypeEnum;
import com.arpa.ntocc.common.domain.enums.PartyTypeEnum;
import com.arpa.ntocc.common.domain.vo.ResourceVueVO;
import com.arpa.ntocc.common.domain.vo.RoleVO;
import com.arpa.ntocc.common.mapper.ShipmentMapper;
import com.arpa.ntocc.common.mapper.UserLoginMapper;
import com.arpa.ntocc.common.service.IPartyResourceService;
import com.arpa.ntocc.common.service.IResourceService;
import com.arpa.ntocc.common.service.IRoleService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.rs.request.OAuthAccessResourceRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.arpa.ntocc.common.domain.dto.UserInfoDTO.*;

@Component
@Log4j2
public class AuthorizeTokenService {

    private final IRoleService roleService;
    private final IResourceService resourceService;
    private final IPartyResourceService partyResourceService;
    @javax.annotation.Resource
    private ShipmentMapper shipmentMapper;
    @javax.annotation.Resource
    private UserLoginMapper userLoginMapper;
    public static final String COLON = ":";
    /**
     * token缓存
     * 设置10天失效时间（注意不设置失效时间，会导致redis溢出）
     * key: token  value: partyCode_ClientType
     * key: partyCode_ClientType  value: token
     */
    @CreateCache(name = "token"  + COLON, timeUnit = TimeUnit.HOURS, expire = 16)
//    @CreateCache(name = "token"  + COLON,  expire = 10 * 24 * 60 * 60)
    private Cache<String, String> tokenCache;

    /**
     * 用户信息，角色，权限缓存
     * 设置10天失效时间（注意和token缓存失效时间设置一致）
     */
    //@CreateCache(name = "userinfo"  + COLON, timeUnit = TimeUnit.HOURS, expire = 1)
    @CreateCache(name = "userinfo"  + COLON, expire = 10 * 24 * 60 * 60)
    private Cache<String, UserInfoDTO> userInfoCache;


    public AuthorizeTokenService(IRoleService roleService, IResourceService resourceService, IPartyResourceService partyResourceService) {
        this.roleService = roleService;
        this.resourceService = resourceService;
        this.partyResourceService = partyResourceService;
    }

    /**
     * 获取当前登录账号code
     *
     * @return
     */
    public String getCurrentPartyCode() {
        String partyCode = null;
        try {
            HttpServletRequest request = HttpUtil.getRequest();
            if (request != null) {
                //构建OAuth资源请求
                OAuthAccessResourceRequest oauthRequest = new OAuthAccessResourceRequest(request);
                //获取Access Token
                String accessToken = oauthRequest.getAccessToken();
                partyCode = getPartyCode(accessToken);
            }
        } catch (OAuthProblemException e) {
            log.error(StrConsts.CATCH_OAUTH_MESSAGE + e.getDescription());
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
        }
        return partyCode;
    }

    /**
     * 获取当前登录的客户端
     *
     * @return
     */
    public ClientTypeEnum getCurrentClientType() {
        try {
            HttpServletRequest request = HttpUtil.getRequest();
            if (request != null) {
                //构建OAuth资源请求
                OAuthAccessResourceRequest oauthRequest = new OAuthAccessResourceRequest(request);
                //获取Access Token
                String accessToken = oauthRequest.getAccessToken();
                String clientId = getClientType(accessToken);
                return ClientTypeEnum.valueOf(clientId);
            }
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
        }
        return ClientTypeEnum.WEB_WMS;
    }

    /**
     * 添加token
     * key：token_[token] value： userLoginId
     * key: token_[userLoginId_clientId] value：token
     *
     * @param clientType  客户端类型
     * @param accessToken token
     * @param partyCode   用户标识
     * @return
     */
    public String addAuthorizeToken(String clientType, String accessToken, String partyCode) {
        //先删除用户的老token，避免redis溢出（相同客户端互斥登录）
        String partyCodeClientType = partyCode + COLON + clientType;
        String oldToken = tokenCache.get(partyCodeClientType);
        //web端登录的先不互斥登录，方便大家测试
        if (StringUtils.isNotEmpty(oldToken) && !"WEB".equals(clientType)) {
            tokenCache.remove(oldToken);
        }
        tokenCache.put(accessToken, partyCodeClientType);
        tokenCache.put(partyCodeClientType, accessToken);
        return accessToken;
    }

    /**
     * 校验token合法性
     *
     * @return
     */
   /* public boolean checkTokenAvailable(String accessToken) {
        //测试环境发现这个地方会存在从缓存获取的值为null的情况（但是redis是有值的），导致调用接口提示需要登录，这里循环3次再次获取防止缓存获取error导致的校验错误
        for (int i = 0; i < 3; i++) {
            try {
                CacheGetResult<String> cacheResult = tokenCache.GET(accessToken);
                if (cacheResult.isSuccess()) {
                    return true;
                } else if (cacheResult.getResultCode() == CacheResultCode.NOT_EXISTS) {
                    return false;
                }
                Thread.sleep(100);
            } catch (Exception e) {
                log.error(StrConsts.CATCH_MESSAGE, e);
            }
        }
        return false;
    }  */

    /**
     * 校验token合法性
     *
     * @return
     */
    public boolean checkTokenAvailable(String accessToken) {
        //try {
        //    CacheGetResult<String> cacheResult = tokenCache.GET(accessToken);
        //    if (cacheResult.isSuccess()) {
        //        refreshRedis(accessToken, cacheResult.getValue());
        //        return true;
        //    } else if (cacheResult.getResultCode() == CacheResultCode.NOT_EXISTS) {
        //        return false;
        //    }
        //} catch (Exception e) {
        //    log.error(StrConsts.CATCH_MESSAGE, e);
        //    return false;
        //}
        //return false;


        String partyCodeClientType = tokenCache.get(accessToken);
        //增加获取缓存数据健壮性
        for (int i = 0; i < 3; i++) {
            if (partyCodeClientType == null) {
                sleep();
                partyCodeClientType = tokenCache.get(accessToken);
            } else {
                break;
            }
        }
        if (StringUtils.isBlank(partyCodeClientType)) {
            return false;
        } else {
            refreshRedis(accessToken, partyCodeClientType);
            return true;

        }
    }

    /**
     * 获取登录用户标识
     *
     * @param accessToken
     * @return
     */
    public String getPartyCode(String accessToken) {
        String partyCodeClientType = tokenCache.get(accessToken);
        //增加获取缓存数据健壮性
        for (int i = 0; i < 3; i++) {
            if (partyCodeClientType == null) {
                sleep();
                partyCodeClientType = tokenCache.get(accessToken);
            } else {
                break;
            }
        }
        if (StringUtils.isBlank(partyCodeClientType)) {
            return null;
        }
        return partyCodeClientType.split(COLON)[0];
    }

    /**
     * 获取登录客户端
     *
     * @param accessToken
     * @return
     */
    public String getClientType(String accessToken) {
        String partyCodeClientType = tokenCache.get(accessToken);
        //增加获取缓存数据健壮性
        for (int i = 0; i < 3; i++) {
            if (partyCodeClientType == null) {
                sleep();
                partyCodeClientType = tokenCache.get(accessToken);
            } else {
                break;
            }
        }
        if (StringUtils.isBlank(partyCodeClientType)) {
            return null;
        }
        List<String> temp = StrUtil.splitTrim(partyCodeClientType, COLON, 2);
        return temp.get(1);
    }

    /**
     * 清除登录token
     *
     * @param token
     */
    public void deleteByToken(String token) {
        tokenCache.remove(token);
    }

    /**
     * 添加用户信息，角色，权限
     *
     * @param party
     */
    public UserInfoDTO addUserInfo(Party party, Map<String, Object> authorizeData, String clientType) {
        //查询用户角色
        List<Role> roleList = roleService.listByPartyCode(party.getCode());
        List<RoleVO> roleVOList;
        if (!CollectionUtils.isEmpty(roleList)) {
            roleVOList = roleList.stream().map(role -> {
                RoleVO roleVO = new RoleVO();
                BeanUtil.copyProperties(role, roleVO);
                roleVO.setRoles(role.getRole());
                return roleVO;
            }).collect(Collectors.toList());
        } else {
            throw new PermissionException("没有访问权限，请联系管理员！");
        }
        //查询用户资源
        List<Resource> resourceList = resourceService.listByPartyCodeAndBranchCode(party.getCode(), party.getBranchCode());
        if (resourceList == null || resourceList.size() == 0) {
            throw new PermissionException("没有访问权限，请联系管理员！");

        }
        //组装成ResourceVueVO
        List<ResourceVueVO> resourceVOList = resourceList.stream().map(resource -> {
            ResourceVueVO resourceVO = new ResourceVueVO();
            BeanUtil.copyProperties(resource, resourceVO);
            resourceVO.setPath(resource.getUrl());
            resourceVO.setMeta(resource.getTitle(), resource.getIcon(), resource.isNoCache());
            return resourceVO;
        }).collect(Collectors.toList());
        //组装所有权限
        List<String> permissionList = resourceService.getAllPermissionList(resourceList);
        UserInfoDTO userInfoDTO = new UserInfoDTO();
        userInfoDTO.setParty(party);
        userInfoDTO.setRoleList(roleVOList);
        userInfoDTO.setResourceList(resourceVOList);
        userInfoDTO.setPermissionlist(permissionList);

        String authorizeDataCode = MapUtil.getStr(authorizeData, AUTHORIZE_DATA_CODE_KEY);


        if (party.getPartyType().equals(PartyTypeEnum.PLAT_ADMIN) || party.getPartyType().equals(PartyTypeEnum.SUPER_ADMIN)) {
            //管理员获取所有启用，并开启库位管理的仓库和货主
            List<Map<String, Object>> warehouseMap = userLoginMapper.getAllWarehouseForAdmin( party.getBranchCode());
            userInfoDTO.setWarehouseList(warehouseMap);
            List<Map<String, Object>> shipmentMap = userLoginMapper.getAllShipmentForAdmin( party.getBranchCode());
            userInfoDTO.setShipmentList(shipmentMap);
        } else {

            String warehouseDate = MapUtil.getStr(authorizeData, AUTHORIZE_WAREHOUSE_CODES);
            if (StrUtil.isNotBlank(warehouseDate)) {
                List<String> warehouseCodes = JSONUtil.toList(JSONUtil.parseArray(warehouseDate), Map.class)
                        .stream().map(m -> MapUtil.getStr(m, "warehouse")).collect(Collectors.toList());
                if (IterUtil.isNotEmpty(warehouseCodes)) {
                    List<Map<String, Object>> warehouseMap = userLoginMapper.getUserloginWarehouse(warehouseCodes);
                    userInfoDTO.setWarehouseList(warehouseMap);
                }
            }
            String shipmentDate = MapUtil.getStr(authorizeData, AUTHORIZE_SHIPMENT_CODES);
            if (StrUtil.isNotBlank(shipmentDate)) {
                List<String> shipmentCodes = JSONUtil.toList(JSONUtil.parseArray(shipmentDate), Map.class)
                        .stream().map(m -> MapUtil.getStr(m, "shipment")).collect(Collectors.toList());
                if (IterUtil.isNotEmpty(shipmentCodes)) {
                    List<Map<String, Object>> shipmentMap = userLoginMapper.getUserloginShipment(shipmentCodes);
                    userInfoDTO.setShipmentList(shipmentMap);
                }
            }
        }

        //查主信息
        if (StrUtil.equals(UserLogin.USER_LOGIN_TYPE_SHIPMENT, MapUtil.getStr(authorizeData, AUTHORIZE_DATA_TYPE_KEY))) {

            Shipment shipment = shipmentMapper.selectOne(new QueryWrapper<Shipment>().lambda()
                    .eq(Shipment::getPartyCode, authorizeDataCode));
            userInfoDTO.setShipment(shipment);
            authorizeData.put(AUTHORIZE_DATA_KEY, shipment);
        }
        userInfoDTO.setAuthorizeData(authorizeData);

        String partyCodeClientType = party.getCode() + COLON + clientType;
        userInfoCache.put(partyCodeClientType, userInfoDTO);
        return userInfoDTO;
    }



    /**
     * 获取用户信息，角色，权限
     *
     * @param partyCode
     */
    public UserInfoDTO getUserInfo(String partyCode) {
        ClientTypeEnum clientType = getCurrentClientType();
        String userinfoKey = partyCode + COLON + clientType.getValue();
        UserInfoDTO userInfoDTO = userInfoCache.get(userinfoKey);
        //增加获取缓存健壮性
        for (int i = 0; i < 3; i++) {
            if (userInfoDTO == null) {
                sleep();
                userInfoDTO = userInfoCache.get(userinfoKey);
            } else {
                break;
            }
        }
        if (userInfoDTO != null && !CollectionUtils.isEmpty(userInfoDTO.getResourceList())) {
            //组装resource为树形结构
            List<ResourceVueVO> resourceTree = treeResource(userInfoDTO.getResourceList(), 0, 3);
            userInfoDTO.setResourceList(resourceTree);
        }
        if(ObjectUtil.isNotNull(userInfoDTO.getParty())){
            if(StringUtils.isBlank(userInfoDTO.getParty().getPhone())){
                userInfoDTO.getParty().setPhone(userInfoDTO.getParty().getCode());
            }
        }
        return userInfoDTO;
    }

    /**
     * 获取用户仓库、货主授权信息
     */
    public Map<String, Object> getAuthorizeData(String partyCode) {
        ClientTypeEnum clientType = getCurrentClientType();
        String userinfoKey = partyCode + COLON + clientType.getValue();
        UserInfoDTO userInfoDTO = userInfoCache.get(userinfoKey);

        if (userInfoDTO != null) {
            return userInfoDTO.getAuthorizeData();
        }
        return null;
    }

    /**
     * 获取用户信息，角色，权限
     *
     * @param authorizeDate
     */
    public UserInfoDTO changeUserInfo(String partyCode, Map<String, Object> authorizeDate, String dataType, String authorizeDataCode) {
        ClientTypeEnum clientType = getCurrentClientType();
        String userinfoKey = partyCode + COLON + clientType.getValue();
        UserInfoDTO userInfoDTO = userInfoCache.get(userinfoKey);
        userInfoDTO.setAuthorizeData(authorizeDate);

        if (StrUtil.equals(UserLogin.USER_LOGIN_TYPE_SHIPMENT, dataType)) {

            Shipment shipment = shipmentMapper.selectOne(new QueryWrapper<Shipment>().lambda()
                    .eq(Shipment::getPartyCode, authorizeDataCode));
            userInfoDTO.setShipment(shipment);
        }


        userInfoCache.put(userinfoKey, userInfoDTO);
        return userInfoDTO;
    }

    /**
     * 获取当前登录用户信息，角色，权限
     */
    public UserInfoDTO getUserInfo() {
        String partyCode = getCurrentPartyCode();
        ClientTypeEnum clientType = getCurrentClientType();
        String userinfoKey = partyCode + COLON + clientType.getValue();
        UserInfoDTO userInfoDTO = userInfoCache.get(userinfoKey);
        //增加获取缓存数据健壮性
        for (int i = 0; i < 3; i++) {
            if (userInfoDTO == null) {
                sleep();
                userInfoDTO = userInfoCache.get(userinfoKey);
            } else {
                break;
            }

        }
        return userInfoDTO;
    }

    /**
     * 组装resource为树形结构
     *
     * @param resourceList
     * @param level
     * @param maxLevel     最大总共获取多少级
     */
    private List<ResourceVueVO> treeResource(List<ResourceVueVO> resourceList, int level, int maxLevel) {
        List<ResourceVueVO> topResourceList = new ArrayList<>();
        if (IterUtil.isNotEmpty(resourceList)) {
            topResourceList = resourceList.stream().filter(resourceVO -> resourceVO.getLevel() == level).collect(Collectors.toList());
        }
        if (IterUtil.isNotEmpty(topResourceList)) {
            topResourceList.forEach(resource -> {
                resource.setChildren(getChild(resource.getCode(), resourceList, maxLevel));
            });
        }
        return topResourceList;
    }

    /**
     * 获取子列表(递归)
     *
     * @param parentCode   父级code
     * @param resourceList 总数据
     * @param maxLevel     最大总共获取多少级
     * @return
     */
    private List<ResourceVueVO> getChild(String parentCode, List<ResourceVueVO> resourceList, int maxLevel) {
        List<ResourceVueVO> child = resourceList.stream().filter(resource -> parentCode.equals(resource.getParentCode())).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(child)) {
            child.forEach(resource -> {
                if (resource.getLevel() < maxLevel) {//最大只展示maxLevel级
                    resource.setChildren(getChild(resource.getCode(), resourceList, maxLevel));
                }
            });
        }
        return child;
    }

    /**
     * 获取用户所有权限字符串
     *
     * @param partyCode
     * @return
     */
    public List<String> listPermissionStrListByPartyCode(String partyCode) {
        List<String> permissionList = new ArrayList<>();
        ClientTypeEnum clientType = getCurrentClientType();
        String userinfoKey = partyCode + COLON + clientType.getValue();
        UserInfoDTO userInfoDTO = userInfoCache.get(userinfoKey);
        if (userInfoDTO != null) {
            permissionList = userInfoDTO.getPermissionlist();
        }
        return permissionList;
    }

    /**
     * 校验密码和时间因子
     *
     * @param pd
     * @param time
     * @return
     */
    public boolean validatePassAndTime(String pd, String time) {
        boolean result = false;
        boolean timeResult = false;
        boolean passwdResult = false;
        try {
            //校验时间因子
            Date now = new Date();
            Date timeFactor = DateUtil.parse(time, "yyyyMMddHHmmss");
            long diff = DateUtil.between(now, timeFactor, DateUnit.HOUR);
            //相差24小时校验通过
            if (diff <= 24 && diff >= -24) {
                timeResult = true;
            }
            //校验密码
            String decodePass = Base64.decodeStr(pd);
            String decodeTime = decodePass.split("_arpa_")[1];
            if (decodeTime.equals(time)) {
                passwdResult = true;
            }
            result = timeResult && passwdResult;
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
        }
        return result;
    }

    /**
     * 校验登录类型
     *
     * @param loginType
     * @param partyType
     * @return
     */
    public boolean validateLoginType(String loginType, PartyTypeEnum partyType) {
        boolean result = false;
        try {
            if (StringUtils.isNotEmpty(loginType)) {
                if (PartyTypeEnum.SHIPMENT.getValue().equals(loginType)) {
                    if (PartyTypeEnum.SHIPMENT == partyType || PartyTypeEnum.SHIPMENT_COMPANY == partyType) {
                        result = true;
                    }
                } else if (PartyTypeEnum.DRIVER.getValue().equals(loginType)) {
                    if (PartyTypeEnum.DRIVER == partyType || PartyTypeEnum.DRIVER_LEADER == partyType) {
                        result = true;
                    }
                } else if ("ONLYDRIVER".equals(loginType) && PartyTypeEnum.DRIVER == partyType) {
                    result = true;
                }
            } else {
                if (PartyTypeEnum.SHIPMENT == partyType || PartyTypeEnum.SHIPMENT_COMPANY == partyType) {
                    result = false;
                }
                //没有登录类型的直接校验通过
                result = true;
            }
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
        }
        return result;
    }

    /**
     * 解密前台加密的密码
     *
     * @param password
     * @return
     */
    public String decodePassword(String password) {
        String decodePass = Base64.decodeStr(password);
        String realPass = decodePass.split("_arpa_")[0];
        return realPass;
    }

    /**
     * 获取仓库绑定的货主信息
     *
     * @param warehouseCode
     * @return
     */
    public List<String> getShipmentCodes(String warehouseCode, List<String> shipmentCodes) {
        return shipmentMapper.getShipmentCodesByWarehouseCode(warehouseCode, shipmentCodes);
    }


    /**
     * 刷新登录信息，延长超期时间
     *
     * @param token
     * @param value
     * @author liuxr
     * @date 2021/7/22 10:49
     */
    private void refreshRedis(String token, String value) {
        tokenCache.PUT(token, value);
    }


    /**
     * 添加用户信息，角色，权限
     *
     * @param party
     */
    public UserInfoDTO getUserInfo(Party party, Map<String, Object> authorizeData, String clientType) {
        String groupCode = party.getBranchCode();

        List<PartyResource> partyResourceList ;

        if(party.getPartyType().equals(PartyTypeEnum.GROUP_ADMIN)){
            partyResourceList = partyResourceService.list(Wrappers.lambdaQuery(PartyResource.class)
                    .select(PartyResource::getCode,PartyResource::getResourceCode)
                    .eq(PartyResource::getPartyCode, groupCode)
            );
        }else{
            partyResourceList = partyResourceService.list(Wrappers.lambdaQuery(PartyResource.class)
                    .select(PartyResource::getCode,PartyResource::getResourceCode)
                    .eq(PartyResource::getGroupCode, groupCode)
                    .eq(PartyResource::getPartyCode, party.getCode())
            );
        }
        if (IterUtil.isEmpty(partyResourceList)) {
            throw new PermissionException("没有访问权限，请联系管理员！");
        }
        List<String> resourceCodes = partyResourceList.stream().map(PartyResource::getResourceCode).collect(Collectors.toList());

        //查询用户资源
        List<Resource> resourceList = resourceService.list(Wrappers.lambdaQuery(Resource.class)
                .in(Resource::getCode,resourceCodes)).stream().sorted(Comparator.comparing(Resource::getSort))
                .collect(Collectors.toList());;
        if (IterUtil.isEmpty(resourceList)) {
            throw new PermissionException("没有访问权限，请联系管理员！");
        }
        //组装成ResourceVueVO
        List<ResourceVueVO> resourceVOList = resourceList.stream().map(resource -> {
            ResourceVueVO resourceVO = new ResourceVueVO();
            BeanUtil.copyProperties(resource, resourceVO);
            resourceVO.setPath(resource.getUrl());
            resourceVO.setMeta(resource.getTitle(), resource.getIcon(), resource.isNoCache());
            return resourceVO;
        }).collect(Collectors.toList());
        //组装所有权限
        List<String> permissionList = resourceService.getAllPermissionList(resourceList);
        UserInfoDTO userInfoDTO = new UserInfoDTO();
        userInfoDTO.setParty(party);
        userInfoDTO.setResourceList(resourceVOList);
        userInfoDTO.setPermissionlist(permissionList);
        //if (party.getPartyType().equals(PartyTypeEnum.GROUP_ADMIN)) {
        //    //管理员获取所有启用，并开启库位管理的仓库和货主
        //    List<Map<String, Object>> warehouseMap = userLoginMapper.getAllWarehouseForAdmin(groupCode);
        //    userInfoDTO.setWarehouseList(warehouseMap);
        //    List<Map<String, Object>> shipmentMap = userLoginMapper.getAllShipmentForAdmin(groupCode);
        //    userInfoDTO.setShipmentList(shipmentMap);
        //} else {
            String warehouseCodesStr = MapUtil.getStr(authorizeData, AUTHORIZE_WAREHOUSE_CODES);
            if (StrUtil.isNotBlank(warehouseCodesStr)) {
                List<String> warehouseCodeList = StrUtil.split(warehouseCodesStr, ',');
                if (IterUtil.isNotEmpty(warehouseCodeList)) {
                    List<Map<String, Object>> warehouseMap = userLoginMapper.getUserloginWarehouse(warehouseCodeList);
                    userInfoDTO.setWarehouseCodeList(warehouseCodeList);
                    userInfoDTO.setWarehouseList(warehouseMap);
                }
            }
            String shipmentDate = MapUtil.getStr(authorizeData, AUTHORIZE_SHIPMENT_CODES);
            if (StrUtil.isNotBlank(shipmentDate)) {
                List<String> shipmentCodes = StrUtil.split(shipmentDate, ',');
                if (IterUtil.isNotEmpty(shipmentCodes)) {
                    List<Map<String, Object>> shipmentMap = userLoginMapper.getUserloginShipment(shipmentCodes);
                    userInfoDTO.setShipmentCodeList(shipmentCodes);
                    userInfoDTO.setShipmentList(shipmentMap);
                }
            }
        //}

        userInfoDTO.setAuthorizeData(authorizeData);

        String partyCodeClientType = party.getCode() + COLON + clientType;
        userInfoCache.put(partyCodeClientType, userInfoDTO);
        return userInfoDTO;
    }

    /**
     * 添加用户信息，角色，权限
     *
     * @param party
     */
    public UserInfoDTO addOmsUserInfo(Party party, Map<String, Object> authorizeData, String clientType) {
        String groupCode = party.getBranchCode();

        //查询用户资源
        List<Resource> resourceList = resourceService.list(new QueryWrapper<Resource>().lambda().eq(Resource::getBranchCode,"arpa"));
        if (IterUtil.isEmpty(resourceList)) {
            throw new PermissionException("没有访问权限，请联系管理员！");
        }
        //组装成ResourceVueVO
        List<ResourceVueVO> resourceVOList = resourceList.stream().map(resource -> {
            ResourceVueVO resourceVO = new ResourceVueVO();
            BeanUtil.copyProperties(resource, resourceVO);
            resourceVO.setPath(resource.getUrl());
            resourceVO.setMeta(resource.getTitle(), resource.getIcon(), resource.isNoCache());
            return resourceVO;
        }).collect(Collectors.toList());
        //组装所有权限
        List<String> permissionList = resourceService.getAllPermissionList(resourceList);
        UserInfoDTO userInfoDTO = new UserInfoDTO();
        userInfoDTO.setParty(party);
//        userInfoDTO.setRoleList(roleVOList);
        userInfoDTO.setResourceList(resourceVOList);
        userInfoDTO.setPermissionlist(permissionList);

        String authorizeDataCode = MapUtil.getStr(authorizeData, AUTHORIZE_DATA_CODE_KEY);

        String warehouseCodesStr = MapUtil.getStr(authorizeData, AUTHORIZE_WAREHOUSE_CODES);
        if (StrUtil.isNotBlank(warehouseCodesStr)) {
            List<String> warehouseCodeList = StrUtil.split(warehouseCodesStr, ',');
            if (IterUtil.isNotEmpty(warehouseCodeList)) {
                List<Map<String, Object>> warehouseMap = userLoginMapper.getUserloginWarehouse(warehouseCodeList);
                userInfoDTO.setWarehouseCodeList(warehouseCodeList);
                userInfoDTO.setWarehouseList(warehouseMap);
            }
        }
        String shipmentDate = MapUtil.getStr(authorizeData, AUTHORIZE_SHIPMENT_CODES);
        if (StrUtil.isNotBlank(shipmentDate)) {
            List<String> shipmentCodes = StrUtil.split(shipmentDate, ',');
            if (IterUtil.isNotEmpty(shipmentCodes)) {
                List<Map<String, Object>> shipmentMap = userLoginMapper.getUserloginShipment(shipmentCodes);
                userInfoDTO.setShipmentCodeList(shipmentCodes);
                userInfoDTO.setShipmentList(shipmentMap);
            }
        }

        //查主信息
        if (StrUtil.equals(UserLogin.USER_LOGIN_TYPE_SHIPMENT, MapUtil.getStr(authorizeData, AUTHORIZE_DATA_TYPE_KEY))) {

            Shipment shipment = shipmentMapper.selectOne(new QueryWrapper<Shipment>().lambda()
                    .eq(Shipment::getPartyCode, authorizeDataCode));
            userInfoDTO.setShipment(shipment);
            authorizeData.put(AUTHORIZE_DATA_KEY, shipment);
        }
        userInfoDTO.setAuthorizeData(authorizeData);

        String partyCodeClientType = party.getCode() + COLON + clientType;
        userInfoCache.put(partyCodeClientType, userInfoDTO);
        return userInfoDTO;
    }

    private void sleep() {
        try {
            Thread.sleep(50L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
